package com.xcexample.electronicclasscard.view;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.appcompat.app.ActionBar;
import androidx.core.content.FileProvider;

import com.blankj.utilcode.util.ToastUtils;
import com.xcexample.electronicclasscard.R;
import com.xcexample.electronicclasscard.log.LogUtils;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;


public class UpdateVersionDialog {
    private final Context context;
    private final int themeResId;
    private final View layout;
    final Dialog dialog;
    private String versionName, updateContent, apk_url, notUpdate, update;
    private View.OnClickListener notUpdateClickListener, updateClickListener;
    private boolean isForceUpdate = false;

    public UpdateVersionDialog(Context context) {
        this(context, R.style.CustomDialogStyle);
    }

    public UpdateVersionDialog setApk_url(String apk_url) {
        this.apk_url = apk_url;
        return this;
    }

    @SuppressLint("InflateParams")
    public UpdateVersionDialog(Context context, int themeResId) {
        this(context, themeResId, LayoutInflater.from(context).inflate(R.layout.dialog_update_version, null));
    }

    /**
     * 自定义layout用这个
     */
    public UpdateVersionDialog(Context context, int themeResId, View layout) {
        this.context = context;
        this.themeResId = themeResId;
        this.layout = layout;
        dialog = new Dialog(context, themeResId);
        dialog.setCancelable(false);
        dialog.setContentView(layout, new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.WRAP_CONTENT));
    }

    public UpdateVersionDialog setVersionName(String versionName) {
        this.versionName = versionName;
        return this;
    }

    public UpdateVersionDialog setUpdateContent(String updateContent) {
        this.updateContent = updateContent;
        return this;
    }

    public UpdateVersionDialog setNotUpdateText(String str) {
        this.notUpdate = str;
        return this;
    }

    public UpdateVersionDialog setUpdateText(String str) {
        this.update = str;
        return this;
    }

    public UpdateVersionDialog setUpdateOnClickListener(View.OnClickListener listener) {
        this.updateClickListener = listener;
        return this;
    }

    public UpdateVersionDialog setNotUpdateOnClickListener(View.OnClickListener listener) {
        this.notUpdateClickListener = listener;
        return this;
    }

    private ProgressBar progressBar;
    private TextView tv_downNum;
    //    private LinearLayout linBtn;
    private LinearLayout linProgress;

    public Dialog build() {
        progressBar = layout.findViewById(R.id.progress);
//        linBtn = layout.findViewById(R.id.lin_btn);
        tv_downNum = layout.findViewById(R.id.progress_text);
        linProgress = layout.findViewById(R.id.lin_p);

        /*设置显不显示*/
        setText(versionName, R.id.tv_version_name);
        setText(updateContent, R.id.tv_update_content);
        setText(notUpdate, R.id.tv_not_update);
        setText(update, R.id.tv_update);
        if (isForceUpdate) {
            layout.findViewById(R.id.tv_not_update).setVisibility(View.GONE);
        } else {
            layout.findViewById(R.id.tv_not_update).setVisibility(View.VISIBLE);
        }
        linProgress.setVisibility(View.VISIBLE);
        downloadApk();

        /*设置点击监听*/
        if (updateClickListener != null) {
            layout.findViewById(R.id.tv_update).setOnClickListener(view -> {
//                linBtn.setVisibility(View.GONE);
                linProgress.setVisibility(View.VISIBLE);
                downloadApk();

            });
        }
        if (notUpdateClickListener != null) {
            layout.findViewById(R.id.tv_not_update).setOnClickListener(view -> {
                notUpdateClickListener.onClick(view);
                dialog.dismiss();
            });
        }
        /*设置宽度*/
        WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
        params.width = (int) (context.getResources().getDisplayMetrics().widthPixels * 0.80);
        dialog.getWindow().setAttributes(params);
        return dialog;
    }

    private static final int DOWN_UPDATE = 1;
    private static final int DOWN_OVER = 2;
    private File ApkFile;
    private int progress;
    private File FILE_SDCARD = Environment.getExternalStorageDirectory();
    private String IMAGE_PATH = "Apk";
    private File FILE_LOCAL = new File(FILE_SDCARD, IMAGE_PATH);
    private File FILE_APK = new File(FILE_LOCAL, "/");

    /* 下载包安装路径 */
    private String savePath = FILE_APK.getAbsolutePath();

    private Runnable mDownApkRunnable = new Runnable() {
        @Override
        public void run() {
            try {
                URL url = new URL(apk_url);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();

                conn.setRequestProperty("Content-type", "application/vnd.android.package-archive");
//                conn.setRequestProperty("Content-type", "application/octet-stream");
                //conn.setRequestProperty("Content-Disposition", "attachment; filename=\"*.zip\"");

                conn.connect();
                int length = conn.getContentLength();
                InputStream is = conn.getInputStream();

                File file = new File(savePath);
                if (!file.exists()) {
                    file.mkdir();
                } else {
                    file.delete();
                }
                String saveFileName = "banpai.apk";
                ApkFile = new File(savePath + saveFileName);
                FileOutputStream fos = new FileOutputStream(ApkFile);

                int count = 0;
                byte buf[] = new byte[1024];
                do {
                    int numRead = is.read(buf);
                    count += numRead;
                    progress = (int) (((float) count / length) * 100);
                    // 更新进度
                    mHandler.sendEmptyMessage(DOWN_UPDATE);
                    if (numRead <= 0) {
                        dialog.dismiss();
                        // 下载完成通知安装
                        mHandler.sendEmptyMessage(DOWN_OVER);
                        break;
                    }
                    fos.write(buf, 0, numRead);
                } while (true);// 点击取消就停止下载.
                fos.close();
                is.close();
            } catch (MalformedURLException e) {
                e.printStackTrace();
                Log.e("printStackTrace", "" + e.getMessage());
            } catch (IOException e) {
                e.printStackTrace();
                Log.e("IOException", "" + e.getMessage());
            }

        }
    };
    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case DOWN_UPDATE:
                    progressBar.setProgress(UpdateVersionDialog.this.progress);
                    String downNum = (UpdateVersionDialog.this.progress + "%") + "";
                    tv_downNum.setText(downNum);
                    break;
                case DOWN_OVER:
                    write_sys_fs("/proc/wdt", 1);
                    boolean install = install(ApkFile.getPath());
                    ToastUtils.showShort("install:" + install);
                    break;
                default:
                    break;
            }
        }
    };

    /**
     * 安装apk
     */
    private void installApk() {
        if (!ApkFile.exists()) {
            return;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            intent.setDataAndType(Uri.fromFile(ApkFile),
                    "application/vnd.android.package-archive");
        } else {
            Uri uri = FileProvider.getUriForFile(
                    context, "com.xcexample.eightclasscard.fileProvider", ApkFile);
            intent.setDataAndType(uri, "application/vnd.android.package-archive");
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
        context.startActivity(intent);
    }

    public boolean install(String apkPath) {
        boolean result = false;
        DataOutputStream dataOutputStream = null;
        BufferedReader errorStream = null;
        try {
            // 申请su权限
            Process process = Runtime.getRuntime().exec("su");
            dataOutputStream = new DataOutputStream(process.getOutputStream());
            // 执行pm install命令
            String command = "pm install -r " + apkPath + "\n";
            dataOutputStream.write(command.getBytes(Charset.forName("utf-8")));
            dataOutputStream.flush();
            dataOutputStream.writeBytes("exit\n");
            dataOutputStream.flush();
            process.waitFor();
            errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            String msg = "";
            String line;
            // 读取命令的执行结果
            while ((line = errorStream.readLine()) != null) {
                msg += line;
            }
            LogUtils.e("install msg is " + msg);
            // 如果执行结果中包含Failure字样就认为是安装失败，否则就认为安装成功
            if (!msg.contains("Failure")) {
                result = true;
            }
        } catch (Exception e) {
            LogUtils.e(e.getMessage(), e);
        } finally {
            try {
                if (dataOutputStream != null) {
                    dataOutputStream.close();
                }
                if (errorStream != null) {
                    errorStream.close();
                }
            } catch (IOException e) {
                LogUtils.e(e.getMessage(), e);
            }
        }
        return result;
    }

    public void write_sys_fs(String sys_fs, int value) {
        String mode = "1";
        try {
            if (value == 0) mode = "0";
            FileOutputStream fops = new FileOutputStream(sys_fs);
            fops.write(mode.getBytes());
            fops.flush();
            fops.close();
            ToastUtils.showShort("执行了看门狗"+mode);
        } catch (FileNotFoundException e) {
            ToastUtils.showShort("FileNotFoundException"+e.getMessage());
            Log.d("err", "found error");
        } catch (IOException e) {
            ToastUtils.showShort("IOException"+e.getMessage());
            Log.d("err", "IO error");
        }
    }


    /**
     * 下载apk
     */
    private void downloadApk() {
        Thread downLoadThread = new Thread(mDownApkRunnable);
        downLoadThread.start();
    }

    private void setText(CharSequence text, int id) {
        if (isValid(text)) {
            TextView textView = (TextView) layout.findViewById(id);
            textView.setText(text);
            textView.setVisibility(View.VISIBLE);
        }
    }

    private boolean isValid(CharSequence text) {
        return text != null && !"".equals(text.toString().trim());
    }

    public UpdateVersionDialog isForceUpdate(boolean isForceUpdate) {
        this.isForceUpdate = isForceUpdate;
        return this;
    }

}


